package hw2.hybrid;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.imageio.stream.FileImageOutputStream;



public class Decriptor {

	public static void main(String[] args) throws Exception {
		byte[] b = readBytesFromFile("rsa_priv.bin");

		PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec( b);
		byte[] decrypted = pkcs8.getEncoded();
		PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec( decrypted );

		PrivateKey pk =  KeyFactory.getInstance( "RSA" ).generatePrivate( spec );
		
		Cipher rsaDec = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
		
		byte[] b2 = readBytesFromFile("sess.bin");
		
		rsaDec.init(Cipher.DECRYPT_MODE, pk);
		byte[] aesKeyBytes = rsaDec.doFinal(b2);
		
		System.out.println(aesKeyBytes);
		
		byte[] iv = readBytesFromFile("iv.bin");
		

		
		SecretKey aesKey = new SecretKeySpec(aesKeyBytes,"AES");
		
		Cipher aesDec = Cipher.getInstance("AES/CBC/PKCS5Padding");
		aesDec.init(Cipher.DECRYPT_MODE, aesKey,new IvParameterSpec(iv));
		
		byte[] htmlFile = readBytesFromFile("hw2.II.html.enc");
		
		byte[] text = aesDec.doFinal(htmlFile);
		System.out.println(new String(text));
		
		writeBytesToFile(text, "hw2.html");
	}

	/**
	 * Reads file fromfile name into a byte[] and returns it 
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	static byte[] readBytesFromFile(String filename) throws IOException {
		File file = new File(filename);
	    InputStream is = new FileInputStream(file);

	    // Get the size of the file
	    long length = file.length();

	    if (length > Integer.MAX_VALUE) {
	        // File is too large
	    }

	    // Create the byte array to hold the data
	    byte[] bytes = new byte[(int)length];

	    // Read in the bytes
	    int offset = 0;
	    int numRead = 0;
	    while (offset < bytes.length
	           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
	        offset += numRead;
	    }

	    // Ensure all the bytes have been read in
	    if (offset < bytes.length) {
	        throw new IOException("Could not completely read file "+filename);
	    }

	    // Close the input stream and return bytes
	    is.close();
	    return bytes;
	}

	/**
	 * Writes a file named <filename> which contains the data <bytes>
	 * @param bytes
	 * @param filename
	 * @throws IOException
	 */
	public static void writeBytesToFile(byte[] bytes, String filename) throws IOException {
		File output = new File(filename);
		FileOutputStream os = new FileOutputStream(output);
		os.write(bytes);
		os.close();
	}

}
